# -*- mode: org; fill-column: 80; -*-
#+TITLE: Functions
#+AUTHOR: Zelphir Kaltstahl
#+STARTUP: content indent align inlineimages entitiesplain nologdone nologreschedule nologredeadline nologrefile
#+TODO: TODO WIP | DONE
#+DATE: <2021-05-13 Do>
#+LANGUAGE: English
#+PRIORITIES: A C C

* Function definitions

#+begin_src sml :results output verbatim replace drawer
(*need to import the infinitely large integer structure to avoid overflows for
big numbers*)

open IntInf;

(*in one function*)
fun fib_naive (n) =
    if n < 2
    then 1
    else fib_naive (n - 1) + fib_naive (n - 2);

(*using pattern matching*)
fun fib_naive_2 (0) = 1
  | fib_naive_2 (1) = 1
  | fib_naive_2 (n) =
    fib_naive (n - 1) + fib_naive (n - 2);

(*avoiding stack overflow by using tail recursion*)
fun fib_tail_recursive 0 = 1
  | fib_tail_recursive 1 = 1
  | fib_tail_recursive n =
    let
        val init_1 = 1;
        val init_2 = 1;
        fun iter (prev_prev, prev, ind) =
            if ind = n
            then prev_prev + prev
            else iter (prev, prev_prev + prev, ind + 1)
    in
        (* starting at 2 because 0 and 1 are already handled in pattern matching
        ,*)
        iter (init_1, init_2, 2)
    end;

fib_naive 10;
fib_naive_2 10;
fib_tail_recursive 100;
#+end_src

#+RESULTS:
:results:
val fib_naive = fn : int -> int
:end:

* Function type

+ expressed using the operator ~->~
+ right-associative: ~T1 -> T2 -> T3~ is the same as ~T1 -> (T2 -> T3)~x

* Example functions

#+begin_src sml :results output verbatim replace drawer
fun upper (character) =
    chr(ord(character) - 32);

fun square (x: real) =
    x * x;
#+end_src

#+RESULTS:
:results:
val upper = fn : char -> char
:end:
